#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#define MEM_SIZE 8192 ///< 总内存大小，单位为字节
char BUFF[MEM_SIZE]; ///< 模拟内存池的缓冲区

/**
 * @struct Block
 * @brief 内存块结构体
 * 
 * 用于管理内存分配和释放，包含指向下一个块的指针、块的大小及其空闲状态。
 */
typedef struct Block {
    struct Block* next; ///< 指向下一个内存块的指针
    size_t size;        ///< 内存块的大小
    bool free;          ///< 内存块的空闲状态
} Block;

#define BLOCK_SIZE sizeof(Block) ///< 定义Block结构的大小
#define ALIGN(size) (((size) + (BLOCK_SIZE - 1)) & ~(BLOCK_SIZE - 1)) ///< 内存对齐宏

Block* freeList[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; ///< 空闲块列表
const size_t blockSizes[] = {8, 16, 32, 64, 128, 256, 512, 1024}; ///< 各种块大小
const int numBlocks = sizeof(blockSizes) / sizeof(blockSizes[0]); ///< 可用块大小的数量
int free_mem_size = MEM_SIZE; ///< 当前空闲内存大小

/**
 * @brief 初始化内存管理器
 * 
 * 清除内存池并初始化空闲块列表。
 */
void initialize() {
    memset(BUFF, 0, MEM_SIZE);
    for (int i = 0; i < numBlocks; ++i) {
        freeList[i] = NULL;
    }
}

/**
 * @brief 获取适合所需大小的块索引
 * 
 * @param size 请求分配的内存大小
 * @return int 适合的块索引，如果没有合适的块返回-1
 */
int getBlockIndex(size_t size) {
    size += BLOCK_SIZE;
    for (int i = 0; i < numBlocks; ++i) {
        if (blockSizes[i] >= size) {
            if (blockSizes[i] > free_mem_size) return -1;
            return i;
        }
    }
    return -1; 
}

/**
 * @brief 分配内存块
 * 
 * @param size 请求分配的内存大小
 * @return void* 指向分配内存块的指针
 */
void* mmalloc(size_t size) {
    int index = getBlockIndex(size);
    if (index == -1) {
        printf("Allocation size too large.\n");
        return NULL;
    }

    if (!freeList[index]) {  
        Block* block = (Block*)(BUFF + MEM_SIZE - free_mem_size);
        block->size = blockSizes[index];
        block->free = false;
        block->next = NULL;
        printf("Allocated block of size %zu bytes.\n", blockSizes[index]);
        free_mem_size -= blockSizes[index];
        return (char*)block + BLOCK_SIZE;
    } else {  
        Block* block = freeList[index];
        freeList[index] = block->next;
        block->free = false;
        printf("Reused block of size %zu bytes.\n", blockSizes[index]);
        free_mem_size -= blockSizes[index];
        return (char*)block + BLOCK_SIZE;
    }
}

/**
 * @brief 释放内存块
 * 
 * @param ptr 指向要释放的内存块的指针
 */
void mfree(void* ptr) {
    if (!ptr) return;

    Block* block = (Block*)((char*)ptr - BLOCK_SIZE);
    int index = getBlockIndex(block->size - BLOCK_SIZE);
    if (index == -1) {
        printf("Invalid block size.\n");
        return;
    }

    block->free = true;
    block->next = freeList[index];
    freeList[index] = block;
    printf("Freed block of size %zu bytes.\n", block->size);
    free_mem_size += blockSizes[index];
}

/**
 * @brief 主函数，测试内存分配和释放功能
 * 
 * 初始化内存管理器，分配和释放内存块，并打印相关信息。
 * 
 * @return int 成功返回0
 */
int main() {
    initialize();
    
    void* ptr1 = mmalloc(16);
    void* ptr2 = mmalloc(128);
    mfree(ptr1);
    void* ptr3 = mmalloc(16);

    return 0;
}
